package com.zh.onlineexam.controller;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zh.onlineexam.common.OperaLog;
import com.zh.onlineexam.common.response.ResultData;
import com.zh.onlineexam.common.response.ReturnCode;
import com.zh.onlineexam.entity.TUserToken;
import com.zh.onlineexam.entity.User;
import com.zh.onlineexam.service.TUserTokenService;
import com.zh.onlineexam.service.UserService;
import com.zh.onlineexam.util.GenerateImgUtil;
import com.zh.onlineexam.util.LoginUtil;
import jodd.util.Base64;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author 29934
 */
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
@Slf4j
@CrossOrigin
public class UserController {
    private final UserService userService;
    private final LoginUtil loginUtil;
    private final TUserTokenService tUserTokenService;

    /**
     * 查询全部用户*/
    @OperaLog(operaModule="用户管理",operaType="查询用户",operaDesc="查询用户")
    @RequestMapping("/listAll")
    public List<User> listAll(@RequestBody User user){
        return userService.list(new LambdaQueryWrapper<User>()
                .like(StrUtil.isNotBlank(user.getRealName()),User::getRealName,user.getRealName())
                .eq(StrUtil.isNotBlank(user.getUserLevel() == null ? null : user.getUserLevel().toString()),User::getUserLevel,user.getUserLevel())
                .like(StrUtil.isNotBlank(user.getPhone()),User::getPhone,user.getPhone()));
    }
    /**
     * 用户登录*/
    @OperaLog(operaModule="系统管理",operaType="用户登录",operaDesc="用户登录")
    @RequestMapping("/login")
    public ResultData<T> login(@RequestBody User user){
        ResultData<T> resultData = new ResultData<T>();
        //根据用户名判断是否存在用户
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name",user.getUserName());
        User one = userService.getOne(wrapper);
        if(ObjectUtils.isEmpty(one)){
            resultData.setCode(ReturnCode.RC300.getCode());
            resultData.setMsg("用户名错误");
            return resultData;
        }
        String errorMsg = loginUtil.checkLogin(user.getUserName(), () -> !BCrypt.checkpw(user.getPassword(), one.getPassword()));
        if(!ObjectUtil.isEmpty(errorMsg)){
            resultData.setCode(ReturnCode.RC300.getCode());
            resultData.setMsg("密码错误,"+errorMsg);
            return resultData;
        }
        //校验密码
        boolean checkpw = BCrypt.checkpw(user.getPassword(), one.getPassword());
        if(!checkpw){
            resultData.setCode(ReturnCode.RC300.getCode());
            resultData.setMsg("密码错误,"+errorMsg);
            return resultData;
        }
        resultData.setCode(ReturnCode.RC100.getCode());
        resultData.setMsg("登录成功");

        //集成redis
        //登录成功后清空redis中保存的错误次数
        loginUtil.loginSuccess(user.getUserName());
        StpUtil.login(one.getId().toString());
        one.setLastActiveTime(new Date());
        userService.updateById(one);
        String token = StpUtil.getTokenValue();
        resultData.setToken(token);
        log.info("token================"+token);
        return resultData;
    }

    /**
     * 添加用户*/
    @OperaLog(operaModule="用户管理",operaType="添加用户",operaDesc="添加用户")
    @RequestMapping("/addUser")
    public ResultData<T> addUser(@RequestBody User user){
        ResultData<T> resultData = new ResultData<T>();
        User one = userService.getOne(new QueryWrapper<User>().eq("user_name", user.getUserName()).last("limit 1"));
        if(ObjectUtils.isEmpty(one)){
            user.setUserUuid(UUID.randomUUID().toString());
            user.setPassword(BCrypt.hashpw(user.getPassword()));
            user.setRole(user.getRole() == null ? 1 : user.getRole());
            user.setStatus(user.getStatus() == null ? 1 : user.getStatus());
            user.setDeleted(user.getDeleted() == null ? 1 : user.getDeleted());
            try {
                BufferedImage bufferedImage = GenerateImgUtil.generateImg(user.getRealName(), "D://", user.getRealName());
                //io流
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, "png", baos);
                Base64 base = new Base64();
                String base64 = Base64.encodeToString(baos.toByteArray());
                user.setImagePath(base64);
            } catch (IOException e) {
                e.printStackTrace();
            }
            userService.save(user);
            resultData.setCode(ReturnCode.RC100.getCode());
        }else{
            resultData.setCode(ReturnCode.RC300.getCode());
            resultData.setMsg("该用户名已注册");
        }
        return resultData;
    }
    /**
     * 删除用户(逻辑删除)*/
    @RequestMapping("/deleteUserById/{id}")
    public ResultData<T> deleteUser(@PathVariable Integer id){
        ResultData<T> resultData = new ResultData<T>();
        boolean removeById = userService.removeById(id);
        if(removeById){
            resultData.setCode(ReturnCode.RC100.getCode());
        }else {
            resultData.setCode(ReturnCode.RC300.getCode());
        }
        return resultData;
    }

    /**
     * 退出登录
     */
    @RequestMapping("/logout")
    public void logout(){
        String tokenValue = StpUtil.getTokenValue();
        log.info("token======"+tokenValue);
        TUserToken tUserToken = tUserTokenService.getOne(new QueryWrapper<TUserToken>().eq("token", tokenValue).last("limit 1"));
        tUserToken.setEndTime(new Date());
        tUserTokenService.updateById(tUserToken);
        StpUtil.logout();
    }

    /**
     * 获取登录用户信息
     */
    @RequestMapping("/getUserInfo")
    public User getUserInfo(){
        Object loginId = StpUtil.getLoginId();
        User one = userService.getOne(new QueryWrapper<User>().eq("id", loginId));
        return one;
    }
}
